package com.base.cn.platform.os.service.course.note;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.dao.course.note.CourseNoteDao;
import com.base.cn.platform.os.entity.course.catalog.CourseCatalog;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.CourseProfile;
import com.base.cn.platform.os.entity.course.note.CourseNote;
import com.base.cn.platform.os.service.course.catalog.CourseCatalogBiz;
import com.base.cn.platform.os.service.course.cou.CourseBiz;
import com.base.cn.platform.os.service.course.cou.CourseProfileBiz;
import com.base.cn.platform.os.service.manage.user.user.CusUserService;
import com.base.cn.platform.os.service.manage.user.user.SetUserDataService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 课程笔记
 *
 * @author SK
 * @since 2018-06-19
 **/
@Service
public class CourseNoteBiz extends BaseBiz<CourseNote, CourseNoteDao> {

    @Autowired
    private CourseBiz courseBiz;
    @Autowired
    private CourseCatalogBiz courseCatalogBiz;
    @Autowired
    private CourseProfileBiz courseProfileBiz;
    @Autowired
    private CusUserService cusUserService;
    @Autowired
    private SetUserDataService<CourseNote> setUserDataService;

    /**
     * 保存课程笔记
     *
     * @param courseNote 课程笔记
     */
    public void saveCourseNote(CourseNote courseNote) {
        save(courseNote);
        cusUserService.updateUserNumberOfStatistics(courseNote.getUserId(), "noteNum", 1);
        CourseProfile profile = courseProfileBiz.findById(courseNote.getCourseId());
        profile.setNoteCount(profile.getNoteCount() + 1);
        courseProfileBiz.updateById(profile, null);
    }

    /**
     * 查询课程笔记列表
     *
     * @param courseNote  查询条件
     * @param count       数量
     * @param setUser     设置用户
     * @param setCourse   设置课程
     * @param setCatalog  设置章节
     * @param setDescribe 设置描述信息 xx > xx hh:mm:ss
     * @return 课程笔记列表
     */
    public List<CourseNote> findCourseNoteList(CourseNote courseNote, Integer count,
                                               boolean setUser, boolean setCourse,
                                               boolean setCatalog, boolean setDescribe) {
        String where = this.where(courseNote);
        List<CourseNote> courseNoteList = find(where, count, null);
        setUserDataService.setUserData(courseNoteList, setUser);
        this.setCourseNoteCourse(courseNoteList, setCourse);
        this.setCourseNoteCourseCatalog(courseNoteList, setCatalog);
        this.setCourseNoteCourseDescribe(courseNoteList, setDescribe, setCatalog);
        return courseNoteList;
    }

    /**
     * 查询课程笔记列表
     *
     * @param courseNote  查询条件
     * @param pagination  分页
     * @param setUser     设置用户
     * @param setCourse   设置课程
     * @param setCatalog  设置章节
     * @param setDescribe 设置描述信息 xx > xx hh:mm:ss
     * @return 课程笔记列表
     */
    public PageInfo<CourseNote> findCourseNotePage(CourseNote courseNote, Pagination pagination,
                                                   boolean setUser, boolean setCourse,
                                                   boolean setCatalog, boolean setDescribe) {
        String where = this.where(courseNote);
        PageInfo<CourseNote> pageInfo = findPage(where, pagination, null);
        setUserDataService.setUserData(pageInfo.getList(), setUser);
        this.setCourseNoteCourse(pageInfo.getList(), setCourse);
        this.setCourseNoteCourseCatalog(pageInfo.getList(), setCatalog);
        this.setCourseNoteCourseDescribe(pageInfo.getList(), setDescribe, setCatalog);
        return pageInfo;
    }

    /**
     * 设置笔记关联课程
     *
     * @param courseNoteList 课程笔记
     * @param setCourse      设置课程
     */
    private void setCourseNoteCourse(List<CourseNote> courseNoteList, boolean setCourse) {
        if (setCourse && ObjectUtils.isNotEmpty(courseNoteList)) {
            String courseIds = DataUtil.joining(courseNoteList, CourseNote::getCourseId);
            Map<BigDecimal, Course> courseMap = courseBiz.findCourseToMapByIds(courseIds, false, false, false, false);
            courseNoteList.forEach((v) -> v.setCourse(courseMap.get(v.getCourseId())));
        }
    }

    /**
     * 设置笔记关联课程章节
     *
     * @param courseNoteList 课程笔记
     * @param setCatalog     设置课程章节
     */
    private void setCourseNoteCourseCatalog(List<CourseNote> courseNoteList, boolean setCatalog) {
        if (setCatalog && ObjectUtils.isNotEmpty(courseNoteList)) {
            String catalogIds = DataUtil.joining(courseNoteList, CourseNote::getCatalogId);
            List<CourseCatalog> courseCatalogList = courseCatalogBiz.findCourseCatalogByIds(catalogIds, false, false, false, false);
            Map<BigDecimal, CourseCatalog> courseCatalogMap = DataUtil.toMap(courseCatalogList, CourseCatalog::getId);
            courseNoteList.forEach((v) -> v.setCatalog(courseCatalogMap.get(v.getCatalogId())));
        }
    }

    /**
     * 设置笔记关联课程章节
     *
     * @param courseNoteList 课程笔记
     * @param setDescribe    设置描述信息 xx > xx hh:mm:ss
     */
    private void setCourseNoteCourseDescribe(List<CourseNote> courseNoteList, boolean setDescribe, boolean setCatalog) {
        if (setDescribe && ObjectUtils.isNotEmpty(courseNoteList)) {
            if (!setCatalog) {
                this.setCourseNoteCourseCatalog(courseNoteList, true);
            }
            String parentIds = courseNoteList.stream()
                    .map(CourseNote::getCatalog) // 获得关联章节
                    .filter(Objects::nonNull) // 筛选出非空
                    .map(CourseCatalog::getParentId) // 获得父章节id
                    .map(String::valueOf) // BigDecimal -> String
                    .distinct() // 去重
                    .collect(Collectors.joining(","));
            List<CourseCatalog> courseCatalogList = courseCatalogBiz.findCourseCatalogByIds(parentIds, false, false, false, false);
            Map<BigDecimal, CourseCatalog> courseCatalogMap = DataUtil.toMap(courseCatalogList, CourseCatalog::getId);
            courseNoteList.forEach((v) -> {
                if (Objects.nonNull(v.getCatalog()) && Objects.nonNull(v.getCatalog().getParentId())) {
                    v.description(courseCatalogMap.get(v.getCatalog().getParentId()));
                }
            });
        }
    }

    private String where(CourseNote courseNote) {
        StringBuilder where= new StringBuilder("1 = 1");
        if (DataUtil.idIsNotNull(courseNote.getCourseId())) {
            where .append( " and courseId = " ).append( courseNote.getCourseId());
        }
        if (DataUtil.idIsNotNull(courseNote.getCatalogId())) {
            where .append( " and catalogId = ").append( courseNote.getCatalogId());
        }
        if (DataUtil.idIsNotNull(courseNote.getUserId())) {
            where .append( " and userId = " ).append( courseNote.getUserId());
        }
        if (DataUtil.isPositive(courseNote.getStatus())) {
            where .append( " and status = " ).append( courseNote.getStatus());
        }
        where.append(" order by id desc");
        return where.toString();
    }
}
